package cn.com.klun.tjy.test.ZookeeperTest;


import org.apache.zookeeper.AsyncCallback.StringCallback;
import org.apache.zookeeper.AsyncCallback.DataCallback;
import org.apache.zookeeper.*;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.KeeperException.Code;
import org.apache.zookeeper.KeeperException.NodeExistsException;
import org.apache.zookeeper.data.Stat;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.util.Random;

import static org.apache.zookeeper.ZooDefs.Ids.OPEN_ACL_UNSAFE;

public class ZkMaster1 implements Watcher {

    private static Logger logger = LoggerFactory.getLogger(ZkMaster1.class);
    static ZooKeeper zk;
    String hostPort;
    static String serverId = Integer.toHexString(new Random().nextInt());
    static boolean isLeader = false;

    // 异步回调添加的方法
    static StringCallback masterCreateCallBack = new StringCallback() {
        @Override
        public void processResult(int rc, String path, Object ctx, String name) {
            switch(Code.get(rc)){
            case CONNECTIONLOSS:
                checkMaster();
                return;
            case OK:
                isLeader =true;
                break;
            default:
                isLeader =false;
            }
            logger.debug("-*-*-*-*-*-*-*-*-*-*-*-*我" + (isLeader?"是":"不是") +"leader");
        }
    };
    // 异步尝试创建主节点
    void asyRunForMaster(){
        zk.create("/master",serverId.getBytes(),OPEN_ACL_UNSAFE,CreateMode.EPHEMERAL,masterCreateCallBack,null);
    }
    // 异步对checkcallback 的调用
    DataCallback masterCheckCallBack = new DataCallback() {
        @Override
        public void processResult(int i, String s, Object o, byte[] bytes, Stat stat) {
            switch(Code.get(i)){
                case CONNECTIONLOSS:
                    checkMaster();
                    return;
                case NONODE:
                    asyRunForMaster();
                    return;
            }
        }
    };
    // 异步检查是否创建主节点
    void asyCheckMaster() {
        zk.getData("/master",false, masterCheckCallBack,null);
    }

    // 检查是否创建主节点
    static boolean checkMaster() {
        while(true){
            try {
                Stat stat = new Stat();
                byte data[] = zk.getData("/master",false,stat);
                isLeader = new String(data).equals(serverId);
                return true;
            } catch (Exception e) {
                return false;
            }
        }
    }
    // 同步运行机制
    void runForMaster() throws  InterruptedException {
        while(true) {
            try {
                zk.create("/master",
                        serverId.getBytes(),
                        OPEN_ACL_UNSAFE,
                        CreateMode.EPHEMERAL);
                isLeader = true;
                break;
            } catch (NodeExistsException e) {
                isLeader = false;
                break;
            } catch (KeeperException e) {
                logger.error("异常信息为",e.getMessage());
                e.printStackTrace();
            }
        }
    }

    private ZkMaster1(String hostPort) {
        this.hostPort = hostPort; //1
    }

    @Override
    public void process(WatchedEvent watchedEvent) {
        logger.debug("一个事务监听器{}", watchedEvent);//3
    }
    void startZK() throws IOException {
        zk = new ZooKeeper(hostPort,15000,this);//2
    }
    void stopZK() throws InterruptedException {
        zk.close();
    }
    public static void main(String args[]) throws Exception {

        ZkMaster1 zk = new ZkMaster1("192.168.137.12:2181");
        zk.startZK();
        zk.asyRunForMaster();
        Thread.sleep(500);
        if(isLeader){
            System.out.println("************是leader");
            Thread.sleep(5000);
        } else {
            System.out.println("************或许别人是leader");
        }
        zk.stopZK();
    }

}
